import { Router } from 'express';
import { body, param, query } from 'express-validator';
import { authenticateToken, authorizeRole } from '../middleware/auth';
import { validateRequest } from '../middleware/validation';
import { generateSlug } from '../lib/utils';
import { prisma } from '../lib/prisma';

const router = Router();

// 获取标签列表
router.get('/', 
  authenticateToken,
  [
    query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
    query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
    query('search').optional().isString().trim(),
    query('sortBy').optional().isIn(['name', 'createdAt', 'usage']).withMessage('排序字段无效'),
    query('sortOrder').optional().isIn(['asc', 'desc']).withMessage('排序顺序无效')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { 
        page = 1, 
        limit = 20, 
        search, 
        sortBy = 'createdAt', 
        sortOrder = 'desc' 
      } = req.query;
      const skip = (Number(page) - 1) * Number(limit);

      // 构建查询条件
      const where: any = {};
      if (search) {
        where.OR = [
          { name: { contains: search as string, mode: 'insensitive' } },
          { description: { contains: search as string, mode: 'insensitive' } }
        ];
      }

      // 构建排序条件
      let orderBy: any = {};
      if (sortBy === 'usage') {
        orderBy = {
          knowledgeBases: {
            _count: sortOrder
          }
        };
      } else {
        orderBy = { [sortBy]: sortOrder };
      }

      // 查询标签
      const [tags, total] = await Promise.all([
        prisma.tag.findMany({
          where,
          select: {
            id: true,
            name: true,
            description: true,
            slug: true,
            color: true,
            createdAt: true,
            updatedAt: true,
            createdBy: {
              select: {
                id: true,
                username: true
              }
            },
            _count: {
              select: {
                knowledgeBases: true
              }
            }
          },
          skip,
          take: Number(limit),
          orderBy
        }),
        prisma.tag.count({ where })
      ]);

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          tags,
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total,
            pages: Math.ceil(total / Number(limit))
          }
        }
      });
    } catch (error) {
      console.error('获取标签列表失败:', error);
      res.status(500).json({ success: false, error: '获取标签列表失败' });
    }
  }
);

// 获取所有标签（用于选择器）
router.get('/all',
  authenticateToken,
  async (req, res) => {
    try {
      const tags = await prisma.tag.findMany({
        select: {
          id: true,
          name: true,
          color: true,
          _count: {
            select: {
              knowledgeBases: true
            }
          }
        },
        orderBy: { name: 'asc' }
      });

      res.json({
        code: 200,
        message: '获取所有标签成功',
        data: tags
      });
    } catch (error) {
      console.error('获取所有标签失败:', error);
      res.status(500).json({ success: false, error: '获取所有标签失败' });
    }
  }
);

// 获取单个标签
router.get('/:id',
  authenticateToken,
  [
    param('id').isString().notEmpty().withMessage('标签ID不能为空')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;
      const tag = await prisma.tag.findUnique({
        where: { id },
        select: {
          id: true,
          name: true,
          description: true,
          slug: true,
          color: true,
          createdAt: true,
          updatedAt: true,
          createdBy: {
            select: {
              id: true,
              username: true
            }
          },
          knowledgeBases: {
            select: {
              id: true,
              title: true,
              status: true,
              createdAt: true
            },
            orderBy: { createdAt: 'desc' },
            take: 20
          },
          _count: {
            select: {
              knowledgeBases: true
            }
          }
        }
      });

      if (!tag) {
        return res.status(404).json({ success: false, error: '标签不存在' });
      }

      res.json({
        code: 200,
        message: '操作成功',
        data: tag });
    } catch (error) {
      console.error('获取标签详情失败:', error);
      res.status(500).json({ success: false, error: '获取标签详情失败' });
    }
  }
);

// 创建标签
router.post('/',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    body('name').isString().trim().isLength({ min: 1, max: 50 }).withMessage('标签名称长度必须在1-50个字符之间'),
    body('description').optional().isString().trim(),
    body('color').optional().isString().trim().matches(/^#[0-9A-F]{6}$/i).withMessage('颜色格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { name, description, color = '#3B82F6' } = req.body;

      // 检查标签名是否已存在
      const existingTag = await prisma.tag.findUnique({ where: { name } });
      if (existingTag) {
        return res.status(400).json({ success: false, error: '标签名已存在' });
      }

      // 生成slug
      const slug = await generateSlug(name, 'tag');

      // 创建标签
      const tag = await prisma.tag.create({
        data: {
          name,
          description,
          slug,
          color,
          createdById: req.user.id
        },
        select: {
          id: true,
          name: true,
          slug: true,
          color: true,
          createdAt: true
        }
      });

      res.status(201).json({ code: 200, data: tag });
    } catch (error) {
      console.error('创建标签失败:', error);
      res.status(500).json({ success: false, error: '创建标签失败' });
    }
  }
);

// 批量创建标签
router.post('/batch',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    body('tags').isArray({ min: 1 }).withMessage('标签数组不能为空'),
    body('tags.*.name').isString().trim().isLength({ min: 1, max: 50 }).withMessage('标签名称长度必须在1-50个字符之间'),
    body('tags.*.description').optional().isString().trim(),
    body('tags.*.color').optional().isString().trim().matches(/^#[0-9A-F]{6}$/i).withMessage('颜色格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { tags } = req.body;
      const createdTags = [];
      const errors = [];

      for (const tagData of tags) {
        try {
          // 检查标签名是否已存在
          const existingTag = await prisma.tag.findUnique({ where: { name: tagData.name } });
          if (existingTag) {
            errors.push({ name: tagData.name, error: '标签名已存在' });
            continue;
          }

          // 生成slug
          const slug = await generateSlug(tagData.name, 'tag');

          // 创建标签
          const tag = await prisma.tag.create({
            data: {
              name: tagData.name,
              description: tagData.description,
              slug,
              color: tagData.color || '#3B82F6',
              createdById: req.user.id
            },
            select: {
              id: true,
              name: true,
              slug: true,
              color: true
            }
          });

          createdTags.push(tag);
        } catch (error) {
          errors.push({ name: tagData.name, error: '创建失败' });
        }
      }

      res.status(201).json({
        code: 200,
        data: {
          createdTags,
          errors,
          summary: {
            total: tags.length,
            success: createdTags.length,
            failed: errors.length
          }
        }
      });
    } catch (error) {
      console.error('批量创建标签失败:', error);
      res.status(500).json({ success: false, error: '批量创建标签失败' });
    }
  }
);

// 更新标签
router.put('/:id',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    param('id').isString().notEmpty().withMessage('标签ID不能为空'),
    body('name').optional().isString().trim().isLength({ min: 1, max: 50 }).withMessage('标签名称长度必须在1-50个字符之间'),
    body('description').optional().isString().trim(),
    body('color').optional().isString().trim().matches(/^#[0-9A-F]{6}$/i).withMessage('颜色格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;
      const updateData = req.body;

      // 检查标签是否存在
      const existingTag = await prisma.tag.findUnique({ where: { id } });
      if (!existingTag) {
        return res.status(404).json({ success: false, error: '标签不存在' });
      }

      // 如果要更新名称，检查是否重复
      if (updateData.name && updateData.name !== existingTag.name) {
        const duplicateTag = await prisma.tag.findUnique({ where: { name: updateData.name } });
        if (duplicateTag) {
          return res.status(400).json({ success: false, error: '标签名已存在' });
        }

        // 重新生成slug
        updateData.slug = await generateSlug(updateData.name, 'tag', id);
      }

      // 更新标签
      const tag = await prisma.tag.update({
        where: { id },
        data: updateData,
        select: {
          id: true,
          name: true,
          slug: true,
          color: true,
          updatedAt: true
        }
      });

      res.json({
        code: 200,
        message: '操作成功',
        data: tag });
    } catch (error) {
      console.error('更新标签失败:', error);
      res.status(500).json({ success: false, error: '更新标签失败' });
    }
  }
);

// 删除标签
router.delete('/:id',
  authenticateToken,
  authorizeRole(['ADMIN']),
  [
    param('id').isString().notEmpty().withMessage('标签ID不能为空')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;

      // 检查标签是否存在
      const existingTag = await prisma.tag.findUnique({ 
        where: { id },
        select: { 
          _count: { 
            knowledgeBases: true 
          } 
        }
      });
      
      if (!existingTag) {
        return res.status(404).json({ success: false, error: '标签不存在' });
      }

      // 检查是否有关联的知识库
      if (existingTag._count.knowledgeBases > 0) {
        return res.status(400).json({ 
          success: false, 
          error: `该标签下有 ${existingTag._count.knowledgeBases} 个知识库，无法删除` 
        });
      }

      // 删除标签
      await prisma.tag.delete({ where: { id } });

      res.json({ code: 200, message: '标签删除成功' });
    } catch (error) {
      console.error('删除标签失败:', error);
      res.status(500).json({ success: false, error: '删除标签失败' });
    }
  }
);

// 批量删除标签
router.delete('/batch',
  authenticateToken,
  authorizeRole(['ADMIN']),
  [
    body('tagIds').isArray({ min: 1 }).withMessage('标签ID数组不能为空'),
    body('tagIds.*').isString().notEmpty().withMessage('标签ID不能为空')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { tagIds } = req.body;
      const deletedTags = [];
      const errors = [];

      for (const tagId of tagIds) {
        try {
          // 检查标签是否存在
          const existingTag = await prisma.tag.findUnique({ 
            where: { id: tagId },
            select: { 
              name: true,
              _count: { 
                knowledgeBases: true 
              } 
            }
          });
          
          if (!existingTag) {
            errors.push({ id: tagId, error: '标签不存在' });
            continue;
          }

          // 检查是否有关联的知识库
          if (existingTag._count.knowledgeBases > 0) {
            errors.push({ 
              id: tagId, 
              name: existingTag.name,
              error: `该标签下有 ${existingTag._count.knowledgeBases} 个知识库，无法删除` 
            });
            continue;
          }

          // 删除标签
          await prisma.tag.delete({ where: { id: tagId } });
          deletedTags.push({ id: tagId, name: existingTag.name });
        } catch (error) {
          errors.push({ id: tagId, error: '删除失败' });
        }
      }

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          deletedTags,
          errors,
          summary: {
            total: tagIds.length,
            success: deletedTags.length,
            failed: errors.length
          }
        }
      });
    } catch (error) {
      console.error('批量删除标签失败:', error);
      res.status(500).json({ success: false, error: '批量删除标签失败' });
    }
  }
);

// 获取标签统计信息
router.get('/stats/overview',
  authenticateToken,
  authorizeRole(['ADMIN']),
  async (req, res) => {
    try {
      const [
        totalTags,
        mostUsedTags,
        recentTags,
        tagsByMonth
      ] = await Promise.all([
        prisma.tag.count(),
        prisma.tag.findMany({
          select: {
            id: true,
            name: true,
            color: true,
            _count: {
              select: {
                knowledgeBases: true
              }
            }
          },
          orderBy: {
            knowledgeBases: {
              _count: 'desc'
            }
          },
          take: 10
        }),
        prisma.tag.findMany({
          select: {
            id: true,
            name: true,
            color: true,
            createdAt: true
          },
          orderBy: { createdAt: 'desc' },
          take: 5
        }),
        prisma.tag.groupBy({
          by: ['createdAt'],
          _count: { createdAt: true },
          orderBy: { createdAt: 'desc' },
          take: 12
        })
      ]);

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          totalTags,
          mostUsedTags,
          recentTags,
          tagsByMonth
        }
      });
    } catch (error) {
      console.error('获取标签统计失败:', error);
      res.status(500).json({ success: false, error: '获取标签统计失败' });
    }
  }
);

export { router as tagRoutes };
